import 'package:async/async.dart';
import 'package:boss/common/common.dart';

import 'package:boss/main.dart';
import 'package:boss/models/commodity.dart';
import 'package:boss/models/commission.dart';
import 'package:boss/models/staff.dart';
import 'package:boss/models/store_table.dart';
import 'package:boss/ui/widget/calendar/util/date_util.dart';
import 'package:boss/util/time_util.dart';
import 'package:boss/util/week_util.dart';
import 'package:flustars/flustars.dart' as flustars;
import 'package:flutter/material.dart';
import 'package:hi_common/hi_common.dart';

class CommissionDetailProvider extends ChangeNotifier {
  List<Staff> staffs = [];

  List<StoreTable> tables = [];

  List<Commodity> commoditys = [];

  Commission commission;

  int commissionId;

  bool get isFixed => commission.isFixed;

  String get commissionAmountTitle => isFixed ? '提成金额' : '提成比例';

  String get commissionAmountHintText => isFixed ? '例如：5¥' : '例如：5%';

  String get commissionAmountUnit => isFixed ? '¥' : '%';

  String get dateRangeText => '${commission.beginDate}-${commission.endDate}';

  String get timeRangeText => '${TimeUtil.hhmmss2hhmm(commission.beginTime)}-${TimeUtil.hhmmss2hhmm(commission.endTime)}';

  int get beginTimeIndex => TimeUtil.string2Int(commission.beginTime);

  int get endTimeIndex => TimeUtil.string2Int(commission.endTime);

  String get weekRangeText {
    final arr = commission.week.split('|');

    String temp = '星期';

    for (final item in arr) {
      temp += JavaWeekUtil.javaString2CHString(item).replaceAll('星期', '');

      if (arr.last != item) temp += '、';
    }

    return temp;
  }

  List<int> get weekIndex => commission.week.split('|').map((item) => JavaWeekUtil.javaString2dart(item) - 1).toList();

  bool get isEnabled => commissionId == null;

  int timeType = 0;

  String commissionStatus;

  bool get isAllCommodity => (commission.commissionCommodityDOList?.length ?? 0) == 0;

  bool get isAllTable => (commission.commissionTableDOList?.length ?? 0) == 0;

  bool get isAllWaiter => (commission.commissionWaiterDOList?.length ?? 0) == 0;

  String get commissionCommodityText => isAllCommodity ? '全部菜品' : '自定义菜品';

  String get commissionWaiterText => isAllWaiter ? '全部员工' : '自定义员工';

  String get commissionTableText => isAllTable ? '全部桌台' : '自定义桌台';

  CommissionDetailProvider(this.commission, this.commissionId, this.commissionStatus);

  setCommissionName(String value) {
    commission.commissionName = value;
    notifyListeners();
  }

  setCommissionWay(String value) {
    commission.commissionWay = value;
    notifyListeners();
  }

  setCommissionAmount(String value) {
    if (commission.commissionWay == Commission.FIXED) {
      commission.commissionAmount = AmountUtil.string2Price(value);
    } else {
      try {
        commission.commissionAmount = AmountUtil.string2Price(value);
      } catch (e) {
        commission.commissionAmount = null;
      }
    }

    notifyListeners();
  }

  setCommissionCommoditys(List<Commodity> commoditys) {
    if (commoditys != null && commoditys.length == 0) return;

    commission.commissionCommodityDOList = commoditys
        ?.map((item) => CommissionCommodityDOList.fromJson({
              'commodityId': item.id,
              'skuId': item.sku?.skuId ?? 0,
            }))
        ?.toList();

    commission.commodityInfos = commoditys
        ?.map((item) => CommodityInfo.fromJson({
              'title': item.title,
              'skuName': item.sku?.skuName,
            }))
        ?.toList();

    notifyListeners();
  }

  changeTimeType(int type) {
    timeType = type;

    if (type == 0) {
      commission.beginDate = null;
      commission.endDate = null;
      commission.beginTime = null;
      commission.endTime = null;
    } else {
      final now = DateTime.now();
      final end = DateUtils.endOfTheMonth(now);

      commission.beginDate = flustars.DateUtil.formatDate(now, format: flustars.DateFormats.y_mo_d);
      commission.endDate = flustars.DateUtil.formatDate(end, format: flustars.DateFormats.y_mo_d);

      commission.beginTime = '00:00:00';
      commission.endTime = '23:59:00';

      commission.week = JavaWeekUtil.javaStringWeek.join('|');
    }

    notifyListeners();
  }

  setDateRange(DateTime begin, DateTime end) {
    commission.beginDate = flustars.DateUtil.formatDate(begin, format: flustars.DateFormats.y_mo_d);
    commission.endDate = flustars.DateUtil.formatDate(end, format: flustars.DateFormats.y_mo_d);
    notifyListeners();
  }

  setTimeRange(String begin, String end) {
    commission.beginTime = begin + ':00';
    commission.endTime = end + ':00';
    notifyListeners();
  }

  setWeek(List<int> res) {
    commission.week = res.map((item) => JavaWeekUtil.dart2JavaString(item + 1)).join('|');
    notifyListeners();
  }

  setStaff(List<Staff> staffs) {
    if (staffs != null && staffs.length == 0) return;

    commission.commissionWaiterDOList = staffs?.map((item) => CommissionWaiterDOList.fromJson({'waiterId': item.userId}))?.toList();

    commission.waiterInfos = staffs?.map((item) => WaiterInfo.fromJson({'rankName': item.roleName, 'realname': item.realname}))?.toList();

    notifyListeners();
  }

  setTable(List<StoreTable> tables) {
    if (tables != null && tables.length == 0) return;

    commission.commissionTableDOList = tables
        ?.map((item) => CommissionTableDOList.fromJson({
              'tableId': item.tableId,
            }))
        ?.toList();

    commission.tableInfos = tables
        ?.map((item) => TableInfo.fromJson({
              'tableName': item.tableName,
              'areaName': item.areaName,
            }))
        ?.toList();
    notifyListeners();
  }

  Future<bool> loadStaff() async {
    try {
      var res = await api.queryAllStaffList();

      if (!res.successful()) {
        return false;
      }

      staffs = res.data;

      return true;
    } catch (e) {
      toast(e.toString());
      return false;
    }
  }

  Future<bool> loadTable() async {
    try {
      var areaTableResponse = await api.queryStoreTableArea();

      if (!areaTableResponse.successful()) {
        return false;
      }

      for (var area in areaTableResponse.data) {
        tables.addAll(area.storeTableList);
      }

      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> loadCommission() async {
    if (commissionId == null) return true;

    try {
      var res = await api.queryCommissionDetail(commissionId);
      if (!res.successful()) {
        return false;
      }

      commission = res.data;

      if (commission.beginDate != null) {
        timeType = 1;
      }

      return true;
    } catch (e) {
      return false;
    }
  }

  Future<Result> loadData() async {
    var res = await Future.wait([loadStaff(), loadTable(), loadCommission()]);

    return res.every((item) => item) ? Result.value(null) : Result.error(Constant.httpErrText);
  }

  copy() {
    commissionId = null;
    commission.id = null;
    notifyListeners();
  }
}
